﻿using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using System.Timers;

namespace Pibby.Core.Web
{
	public class ParallelDownloader
	{
		private ConcurrentQueue<IDownloadable> _downloadQueue;
		private IList<Task> _downloadingTasks;
		private Timer _downloadTimer;

		private int _parallelDownloads;

		public ParallelDownloader(int parallelDownloads)
		{
			_downloadQueue = new ConcurrentQueue<IDownloadable>();
			_downloadingTasks = new List<Task>();
			_downloadTimer = new Timer();

			_parallelDownloads = parallelDownloads;

			_downloadTimer.Elapsed += new ElapsedEventHandler(DownloadTimer_Elapsed);
			// every minute
			_downloadTimer.Interval = 60 * 1000;
			_downloadTimer.Start();

			ServicePointManager.DefaultConnectionLimit = parallelDownloads;
		}

		public void EnqueueFileToDownload(IDownloadable file)
		{
			_downloadQueue.Enqueue(file);
		}

		void DownloadTimer_Elapsed(object sender, ElapsedEventArgs e)
		{
			StartDownload();
		}

		private void StartDownload()
		{
			lock (_downloadingTasks)
			{
				if (_downloadingTasks.Count < _parallelDownloads && _downloadQueue.Count > 0)
				{
					IDownloadable fileToDownload;

					if (_downloadQueue.TryDequeue(out fileToDownload))
					{
						var task = new Task(() =>
						{
							var client = new WebClient();
							client.DownloadFile(fileToDownload.Uri, fileToDownload.LocalPath);

						}, TaskCreationOptions.LongRunning);

						task.ContinueWith(DownloadOverCallback, TaskContinuationOptions.None);

						_downloadingTasks.Add(task);
						task.Start();
					}
				}
			}
		}

		public void DownloadOverCallback(Task downloadingTask)
		{
			lock (_downloadingTasks)
			{
				_downloadingTasks.Remove(downloadingTask);
			}
		}
	}
}